﻿function ProjectTable(container, states, roles, fetchChildren, fetchFilter, baseUrl)
{
    ProjectTable.count = ProjectTable.count ? ProjectTable.count + 1 : 1;
    this.container = $(container);
    this.states = states;
    this.roles = roles;
    this.fetchChildrenFunction = fetchChildren;
    this.fetchFilter = fetchFilter;
    this.filters = {};
    this.baseUrl = baseUrl;
    var tableObj = this;

    this.render = function (projects)
    {
        this.projects = projects;
        this.container.append(this.getControls());

        $('.nameFilter', this.container).val(this.filters.filter);
        $('.stateFilter', this.container).val(this.filters.state);
        $('.roleFilter', this.container).val(this.filters.role);

        table = $(this.getTable());
        this.container.append(table);
        table.append(this.getHeader());


        if (!table.find('tbody').length)
            table.append(stringFormat("<tbody></tbody>"));
        this.loadProjects();
        var thisTable = this;

        $('.nameFilter', this.container).keyup(function ()
        {
            var timeout = 400;
            var filter = $(this);
            var value = filter.val();
            window.setTimeout(function ()
            {
                if (filter.val() == value)
                    thisTable.filter();
            }, timeout);
        });

        $('.stateFilter, .roleFilter', this.container).change(function ()
        {
            thisTable.filter();
        }).ddl({extraWidth:-34});
    }

    this.filter = function ()
    {
        var filter = $('.nameFilter', this.container).val();
        var state = $('.stateFilter', this.container).val();
        var role = $('.roleFilter', this.container).val();

        this.filters = { filter: filter, state: state, role: role };
        var thisTable = this;
        $('#filterImg').show();
        this.fetchFilter(filter, state, role, function (res)
        {
            $('#filterImg').hide();
            thisTable.projects = res;
            thisTable.loadProjects();
        });
    };

    this.loadProjects = function ()
    {
        thisTable = this;

        this.container.find('tbody').html('');
        this.container.find('tbody').append(this.getRows(this.projects, 0));

        if (this.projects.length)
        {
            this.container.find('table').show();
            this._showNoData(false);
        }
        else
        {
            this.container.find('table').hide();
            this._showNoData(true);
        }

        $('tr', table).click(function ()
        {
            $('tr', table).removeClass('Selected');
            $(this).addClass('Selected');
        });

        $('.item .open', table).click(function (e)
        {
            thisTable.fetchChildren.call(thisTable, this);
            e.stopPropagation();
        })
    }

    this._showNoData = function (show)
    {
        if (show)
        {
            var div = $("<div class='coverDiv' style='right:0;left:0;top:40px;bottom:40px'>")
            this.container.append(div)
            div.append(stringFormat("<span class='' style='margin:{0}px {1}px;display:inline-block'>no data</span>", Math.ceil(div.height() / 2) - 12, div.width() / 2 - 27));
        }
        else
            this.container.find('.coverDiv').remove();
    };

    this.getTable = function ()
    {
        return stringFormat("<table id='{0}' cellspacing='0' class='{1}'></table>", "projectTable" + ProjectTable.count, "projectTable DataTable");
    }

    this.getControls = function ()
    {
        return stringFormat("<div cellspacing='0' class='{0}'>\
                                        <select class='stateFilter'>{1}</select>\
                                        <select class='roleFilter'>{2}</select>\
                                        <input class='nameFilter' type='text'/>\
                                        <img id='filterImg' style='display:none' src='{3}/Images/treeview/ajax-loader.gif'/>\
                                     </div>"
                                     , "controls"
                                     , $.map(this.states, function (el)
                                     {
                                         return stringFormat("<option value='{1}'>{0}</option>", el.Key, el.Value);
                                     }).join('')
                                     , $.map(this.roles, function (el)
                                     {
                                         return stringFormat("<option value='{1}'>{0}</option>", el.Key, el.Value);
                                     }).join('')
                                     , this.baseUrl);
    }

    this.fetchChildren = function (element)
    {
        var tr = $(element).closest('tr');
        var parentID = tr.attr('id');
        var parentType = tr.attr('itemType');
        var thisTable = this;

        if ($(element).data('open'))
        {
            $(element).data('open', false);
            $(element).attr('src', thisTable.baseUrl + '/Images/tree_open.gif')
            this.hideChildren(parentID);
        }
        else if ($('[parentID="' + parentID + '"]').length)
        {
            $(element).data('open', true);
            $('[parentID="' + parentID + '"]').show();
            $(element).attr('src', thisTable.baseUrl + '/Images/tree_close.gif');

        }
        else
        {
            $(element).attr('src', thisTable.baseUrl + '/Images/treeview/ajax-loader.gif');

            this.fetchChildrenFunction(parentID, parentType, function (res)
            {
                if (!res || res.length == 0)
                {
                    $(element).css('visibility', 'hidden');
                    return;
                }

                $(element).data('open', true);
                thisTable.addChildren(parentID, res);
                $(element).attr('src', thisTable.baseUrl + '/Images/tree_close.gif');

                $('[parentID="' + parentID + '"]', table).click(function ()
                {
                    $('tr', table).removeClass('Selected');
                    $(this).addClass('Selected');
                })

                $('[parentID="' + parentID + '"] .open', table).click(function (e)
                {
                    thisTable.fetchChildren.call(thisTable, this);
                    e.stopPropagation();
                })
            });
        }
    }

    this.getHeader = function ()
    {
        var html = stringFormat("<thead><tr class='Header'>");
        html += stringFormat("<td></td>", ""); //active icon
        html += stringFormat("<td>{0}</td>", "Name"); // type icon
        //html += stringFormat("<td>{0}</td>", "Project");
        html += stringFormat("<td>{0}</td>", "Start Date");
        html += stringFormat("<td>{0}</td>", "Due Date");
        html += stringFormat("</tr></thead>");

        return html;
    }

    this.getRows = function (items, depth, parentID)
    {
        var html = "";
        for (var i = 0; i < items.length; i++)
            html += this.getRow(items[i], depth, parentID);

        return html;
    }

    this.getRow = function (project, depth, parentID)
    {
        var openImg = project.NumberOfDirectSubItems ?
            stringFormat("<img class='open' src='{0}/Images/tree_open.gif'/>", this.baseUrl) :
            "<span style='width:16px; display:inline-block'></span>";

        var html = stringFormat("<tr id='{0}'  itemType='{1}' parentID='{2}' class='item' depth='{3}'>", project.ID.Value, project.ID.TypeName, parentID, depth);

        html += stringFormat("<td class='status'><img src='{1}/Images/{0}'/></td>", this.getStatusImage(project), this.baseUrl);
        html += stringFormat("<td class='type' style='padding-left:{1}px'>{3}<img class='typeImg' src='{4}/Images/{0}'/><span class='Name'>{2}</span></td>", this.getTypeImage(project), (+depth) * 20, project.Name, openImg, this.baseUrl);
        //html += stringFormat("<td class='ParentProject'>{0}</td>", project.ParentProject_Name ? project.ParentProject_Name : "");
        html += stringFormat("<td class='start'>{0}</td>", project.StartDateString);
        html += stringFormat("<td class='due'>{0}</td>", project.DueDateString);

        html += stringFormat("</tr>");

        return html;
    }

    this.addChildren = function (parentID, workItems)
    {
        var parent = $('#' + parentID);
        var depth = (+parent.attr('depth')) + 1;
        var index = parent.find('td:first').html();
        var newRows = this.getRows(workItems, depth, parentID);
        parent.after(newRows);

        if (this.selected_id && !this.val().id)
            this.select(this.selected_id);
    }

    this.getStatusImage = function (workItem)
    {
        switch (workItem.TrackStatus.Id.Value.toLowerCase())
        {
            case "not active":
                return "iconNotActive.jpg";
                break;
            case "at risk":
                return "iconAtRisk.jpg";
                break;
            case "off track":
                return "iconOffTrack.jpg";
                break;
            case "on track":
            default:
                return "iconOnTrack.jpg";
                break;
        }
    }

    this.getTypeImage = function (workItem)
    {
        switch (workItem.ID.TypeName.toLowerCase())
        {
            case "project":
                return "iconProject.jpg";
                break;
            case "milestone":
                return "iconMilestone.jpg";
                break;
            case "task":
            default:
                return "iconTask.jpg";
                break;
        }
    }

    this.hideChildren = function (parentID)
    {
        var table = this;
        $('[parentID="' + parentID + '"]').hide().each(function ()
        {
            $('.open', this).attr('src', table.baseUrl + '/Images/tree_open.gif').data('open', false);
            var id = $(this).attr('id');
            table.hideChildren(id);
        });
    }

    this.val = function ()
    {
        var id = this.container.find('.Selected').attr('id');
        var name = this.container.find('.Selected .Name').html();
        var typeName = this.container.find('.Selected').attr('itemtype');
        
        return { id: id, name: name, typeName: typeName };
    }

    this.show = function (baseUrl, showNew, onSelect)
    {
        var table = this;

        this.baseUrl = baseUrl;

        $('#dialog-modal').remove();
        var modalString = '\
            <div id="dialog-modal" title="Attach to work item">\
                <div id="tableContainer"></div>\
            </div>'

        var buttons = [
        { text: "Attach", click: function ()
        {
            var val = table.val();
            if (!val.id)
                return;
            $(this).dialog("close");
            if (onSelect)
                onSelect(val);
        }
        },
        { text: "Cancel", click: function () { $(this).dialog("close"); } }];
        if (showNew)
            buttons.push({ text: "New project", click: function ()
            {
                var dialog = $(this);
                table.openNewProject(function (project)
                {
                    dialog.dialog("close");
                    if (onSelect)
                        onSelect({ id: project.ID.Value, name: project.Name, typeName: "Project" });
                });
            }
            });

        $(modalString).dialog({
            height: 300,
            width: Math.min($(window).width() - 80, 600),
            modal: true,
            buttons: buttons,
            close: function ()
            {

            }
        });

        $('#dialog-modal').show_loading(true);

        if (!$('body').data('table'))
        {
            remoteRequest({
                url: table.baseUrl + "/Projects/ProjectTableData",
                contentType: "JSON",
                type: "POST",
                data: null,
                success: function (data)
                {
                    if (data.Data)
                    {
                        data = data.Data;
                        table.container = $('#tableContainer');
                        table.states = data.states;
                        table.roles = data.roles;
                        table.fetchChildrenFunction = function (parentID, type, func)
                        {
                            remoteRequest({
                                url: table.baseUrl + "/Projects/WorkItemChildren",
                                contentType: "JSON",
                                type: "POST",
                                data: encodeValues({ parentID: parentID, parentType: type }),
                                success: function (data)
                                {
                                    func(data.Data);
                                }
                            });
                        };
                        table.fetchFilter = function (filter, state, role, func)
                        {
                            remoteRequest({
                                url: table.baseUrl + "/Projects/WorkItemChildren",
                                contentType: "JSON",
                                type: "POST",
                                data: encodeValues({ filter: filter, state: state, role: role, type: "Project" }),
                                success: function (data)
                                {
                                    func(data.Data);
                                }
                            });
                        };
                        table.filters = {};

                        table.render(data.projects);
                        $('#dialog-modal').show_loading(false);
                        $('body').data('table', table);
                    }
                }
            });
        }
        else
        {
            $('#dialog-modal').show_loading(false);
            $.extend(table, $('body').data('table'));
            table.container = $('#tableContainer');
            table.render(table.projects)
        }

        return false;
    }

    this.openNewProject = function (onCreate)
    {
        var self = this;
        var states = $('.stateFilter').html();
       
        var modalString = stringFormat('\
                <div id="dialog-modal-2" title="New project" class="NewProject">\
                    <div><span class="Label">Name</span><span><input type="text" name="Name"/></span></div>\
                    <div><span class="Label">Description</span><span><textarea rows="3" name="Description"></textarea></span></div>\
                    <div><span class="Label">Project Manager</span><span><select name="ManagerID" class="UserSelect"><select></span></div>\
                    <div><span class="Label">Start Date</span><span><input type="text" name="StartDate" class="Date"/></span></div>\
                    <div><span class="Label">End Date</span><span><input type="text" name="DueDate" class="Date"/></span></div>\
                </div>', states);

        $(modalString).dialog({
            height: 300,
            width: Math.min($(window).width() - 80, 500),
            modal: true,
            buttons: [
                                {
                                    text: "Create project",
                                    click: function ()
                                    {
                                        $('#dialog-modal-2').show_loading(true);

                                        if (self.creatingNew)
                                            return;

                                        var data = $('#dialog-modal-2 input, #dialog-modal-2 select').serialize();
                                        self.creatingNew = true;
                                        var dialog = $(this);
                                        remoteRequest({
                                            url: tableObj.baseUrl + "/projects/create",
                                            contentType: "JSON",
                                            type: "POST",
                                            data: data,
                                            success: function (res)
                                            {
                                                self.creatingNew = false;
                                                $('#dialog-modal-2').show_loading(false);
                                                if (res.Data)
                                                {
                                                    alert("The record has been created.");
                                                    dialog.dialog("close");
                                                    if (onCreate)
                                                        onCreate(res.Data);
                                                }
                                                else if (res.ErrorMessage)
                                                    alert(res.ErrorMessage);
                                                else alert("error");
                                            }
                                        });
                                    }
                                },
                                {
                                    text: "Cancel",
                                    click: function () { $(this).dialog("close"); }
                                }
                            ],
            close: function ()
            {
            }
        });

        $("#dialog-modal-2 .Date").datepicker(
        {
            dateFormat: 'yy-mm-dd',
            showOn: "both",
            buttonImage: tableObj.baseUrl + '/Images/16_icons.gif',
            buttonImageOnly: true
        });

        $('.UserSelect').searchForm({ type: "User", baseUrl: tableObj.baseUrl, filter: "userFilter", pName: "Manager" });
    }

    this.select = function (id)
    {
        this.selected_id = id;

        this.container.find('.Selected').removeClass('.Selected');
        this.container.find(stringFormat("[id='{0}']", id)).addClass('Selected');
    };
}